package com.example.leetcode.c201_c300.c234;
/**
 * 请判断一个链表是否为回文链表。
 *
 * 示例 1:
 *
 * 输入: 1->2
 * 输出: false
 * 示例 2:
 *
 * 输入: 1->2->2->1
 * 输出: true
 * 进阶：
 * 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题？
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/palindrome-linked-list
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */

import com.example.leetcode.common.ListNode;
import com.example.leetcode.common.ListNodeWrapper;

/**
 * 回文链表
 * @author zhanpengguo
 * @date 2020-10-23 8:03
 */
public class Solution {

    public boolean isPalindrome(ListNode head) {
        if (head == null) {
            return true;
        }
        ListNode node = head;
        ListNode middle = getMiddle(node);
        ListNode two = middle.next;
        middle.next = null;
        // 上半截是head，下半截是two
        // 翻转two
        two = revers(two);
        while (two != null) {
            if (two.val != head.val) {
                return false;
            }
            two = two.next;
            head = head.next;
        }
        return true;
    }

    private ListNode getMiddle(ListNode head) {
        ListNode quick = head.next;
        ListNode slow = head;
        while (quick != null && quick.next != null) {
            quick = quick.next.next;
            slow = slow.next;
        }
        return slow;
    }

    private ListNode revers(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        ListNode head = ListNodeWrapper.stringToListNode("[]");
        boolean b = solution.isPalindrome(head);
        System.out.println("是否回文：" + b);
    }
}
